package com.shujia.wyh.day28;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/*
    反射获取类Class文件对象中的成员变量并使用
 */
public class ReflexDemo4 {
    public static void main(String[] args) throws Exception {
        //获取Class文件对象
        Class<?> c1 = Class.forName("com.shujia.wyh.day28.Person");

        //Field[] getFields()
        //返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象。
        //获取当前类所有被public修饰的成员变量
        Field[] fields = c1.getFields();
        for (Field f : fields) {
            System.out.println(f);
        }
        System.out.println("=======================================");
        //Field[] getDeclaredFields()
        //返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象。
        //获取当前类中所有的成员变量，包括私有的，公共的，被保护的，默认的字段,不包括继承的字段。
        Field[] fields2 = c1.getDeclaredFields();
        for (Field field : fields2) {
            System.out.println(field);
        }
        System.out.println("---------------------------------------");
        Class<?> c2 = Class.forName("com.shujia.wyh.day28.B");
        Field[] declaredFields = c2.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        System.out.println("=======================================");
        Constructor<?> con1 = c1.getConstructor();
        Object o = con1.newInstance();
        //获取单个的成员变量
        Field id = c1.getField("id");
        //void set(Object obj, Object value)
        //将指定对象参数上的此 Field对象表示的字段设置为指定的新值。
        id.set(o,"1001");//给对象o中的成员变量id赋值为"1001"
        System.out.println(o);
        System.out.println("=======================================");
        //获取私有的成员变量并赋值
        //NoSuchFieldException: name
//        Field name = c1.getField("name");
        Field name = c1.getDeclaredField("name");
        System.out.println(name);
        //IllegalAccessException
        //暴力访问
        name.setAccessible(true);
        name.set(o,"王五");
        System.out.println(o);
        System.out.println("========================================");
        //默认修饰符的成员变量，不需要暴力访问
        Field age = c1.getDeclaredField("age");
        age.set(o,18);
        System.out.println(o);
        //被保护修饰的成员变量，也不需要暴力访问
        Field address = c1.getDeclaredField("address");
        address.set(o,"安徽合肥");
        System.out.println(o);

    }
}

class A{
    private String aaa;
    public String bbb;
}

class B extends A{

}
